#///////////////////////////////////////////////////////////////////////////////
##.. module:: monitor 
#   
# Monitor a data-stream by periodically analysing it.
# 
#.. func: monitor
# 
# Parameters
# !!!!!!!!!!
# function  
#   The function that that you want to execute periodically. The signature of
#   the function must be ``def function(data, *args, **kwargs)``.
#
# period *(optional)*
#   The period at which you want run `function`, measured in seconds.  Defaults
#   to one hour.
#
# duration *(optional)*
#   The duration of data that you want to process at each point. Defaults to
#   one hour.
#
# upper *(optional)*
#   By default, monitor looks back ``duration`` into the past from the present
#   moment.  However, you can set upper to some other point in the past if you'd
#   prefer (for example if you are testing).  Make sure that ``upper`` is
#   sufficiently far back in the past that you have enough data in the `future`.
#
# kwargs 
#   \*\*kwargs, which are passed to `function`.
#   
# 
## .. codeauthor:: Joe Kwiatkowski http://joejk.com
#///////////////////////////////////////////////////////////////////////////////
import sys
import time
import datetime

from . import readFromDB
from .. import conf
from .. import output 

def monitor(function, period=3600, duration=3600, upper=None, **kwargs):
    if upper == None:
        upper = time.time()
    else: 
        upper = time.mktime(upper.timetuple())


    while True:

        lower = upper - 3600

        data = readFromDB.readFromDB(datetime.datetime.fromtimestamp(lower), 
                                     datetime.datetime.fromtimestamp(upper))

        output.comment('Read %s records.' % len(data['kW']))

        print kwargs
        function(data, **kwargs)

        # And rest:
        print "%sMonitor sleeping for %s seconds" % (conf.COMMENT, period)
        time.sleep(period)

        # Increment `upper` and go again:
        upper += period
